package com.wxpay.springbootwxpay.service.impl;


import com.wxpay.springbootwxpay.config.PayConfig;
import com.wxpay.springbootwxpay.constant.WXConstEnum;
import com.wxpay.springbootwxpay.service.WxPayService;
import com.wxpay.springbootwxpay.wxpayUtils.HttpUtils;
import com.wxpay.springbootwxpay.wxpayUtils.WXPayUtil;
import com.wxpay.springbootwxpay.wxpayUtils.WxPayUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {

    private String grant_type="authorization_code";


    /**
     * 统一下单开始 方法2
     * @param orderNum
     * @param money
     * @param openId
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, String> xcxPayment(String orderNum, double money,String openId) throws Exception {
        log.info("【小程序支付】 统一下单开始, 订单编号="+orderNum);
        SortedMap<String, String> resultMap = new TreeMap<String, String>();
        int flag = 1;//暂时跳过添加
        //做是否更新成功的判断
        if(flag < 0){
            resultMap.put("returnCode", "FAIL");
            resultMap.put("returnMsg", "此订单已支付！");
            log.info("【小程序支付】 此订单已支付！");
        }else if(flag == 0){
            resultMap.put("returnCode", "FAIL");
            resultMap.put("returnMsg", "支付记录生成或更新失败！");
            log.info("【小程序支付】 支付记录生成或更新失败！");
        }else{
            Map<String,String> resMap = this.xcxUnifieldOrder(orderNum,  PayConfig.TRADE_TYPE_JSAPI, money,openId);
            if(WXConstEnum.SUCCESS.equals(resMap.get("return_code"))){
                resultMap.put("appId",WXConstEnum.appId);
                resultMap.put("timeStamp", WxPayUtils.getCurrentTimeStamp());
                resultMap.put("nonceStr", WxPayUtils.makeUUID(32));
                resultMap.put("signType", WXConstEnum.SIGNTYPE);
                resultMap.put("sign", WXPayUtil.generateSignature(resultMap, WXConstEnum.key));
                resultMap.put("returnCode", WXConstEnum.SUCCESS);
                resultMap.put("returnMsg", "OK");
                log.info("【小程序支付】统一下单成功，返回参数:"+ resultMap);
            }else{
                resultMap.put("returnCode", resMap.get("return_code"));
                resultMap.put("returnMsg", resMap.get("return_msg"));
                log.info("【小程序支付】统一下单失败，失败原因:"+ resMap.get("return_msg"));
            }
        }
        return resultMap;
    }

    /**
     * 小程序支付统一下单
     */
    private Map<String,String> xcxUnifieldOrder(String orderNum,String tradeType, double payAmount,String openid) throws Exception{
        //封装参数
        SortedMap<String,String> paramMap = new TreeMap<String,String>();
        paramMap.put("appid", WXConstEnum.appId);
        paramMap.put("mch_id",WXConstEnum.mch_id);
        paramMap.put("nonce_str",WxPayUtils.makeUUID(32).toUpperCase());
        paramMap.put("body","支付订单");
        paramMap.put("out_trade_no", orderNum);
        paramMap.put("total_fee", "18");
        paramMap.put("spbill_create_ip", WxPayUtils.getLocalIp());
        paramMap.put("notify_url", WXConstEnum.notify_url);
        paramMap.put("trade_type", WXConstEnum.TRADETYPE);
        paramMap.put("openid",openid);
        paramMap.put("sign", WXPayUtil.generateSignature(paramMap, WXConstEnum.key).toUpperCase());
        //转换为xml
        String xmlData = WxPayUtils.mapToXml(paramMap);
        log.info("校验xmlData = " + xmlData);
        //请求微信后台，获取预支付ID
        // 统一下单地址 https://api.mch.weixin.qq.com/pay/unifiedorder
        String resXml = HttpUtils.sendPost(PayConfig.WX_PAY_UNIFIED_ORDER, xmlData);
        log.info("【小程序支付】 统一下单响应：\n"+resXml);
        return WxPayUtils.xmlToMap(resXml);
    }

    /**
     * 获取支付订单编号
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(readOnly=false,rollbackFor={Exception.class})
    public int xcxNotify(Map<String,Object> map) throws Exception{
        int flag = 0;
        //支付订单编号
        String orderNo = (String)map.get("out_trade_no");
        if(!StringUtils.isBlank(orderNo)){
            flag=1;
        }
        //检验是否需要再次回调刷新数据
        //TODO 微信后台回调，刷新订单支付状态等相关业务
        return flag;
    }

}
